unit Unit1; 

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  ExtCtrls, Buttons, synaser, LCLType, Spin, ComCtrls,synautil;

type

  { TMainForm }

  TMainForm = class(TForm)
    cbBaud: TComboBox;
    cbHands: TComboBox;
    cbParity: TComboBox;
    cbStopb: TComboBox;
    cbecho: TCheckBox;
    cbcrlf: TCheckBox;
    cbcr: TCheckBox;
    cbaclr: TCheckBox;
    devEdit: TComboBox;
    InpEd: TEdit;
    Groupb1: TGroupBox;
    InpMem2: TMemo;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    InpMem1: TMemo;
    Label7: TLabel;
    Label8: TLabel;
    Parity: TLabel;
    shCTS: TShape;
    shDSR: TShape;
    shCD: TShape;
    shRI: TShape;
    dtrBtn: TSpeedButton;
    rtsBtn: TSpeedButton;
    seDatab: TSpinEdit;
    InfBtn: TSpeedButton;
    clrbtn: TSpeedButton;
    statbutton: TSpeedButton;
    RecvTimer: TTimer;
    procedure cbcrChange(Sender: TObject);
    procedure cbcrlfChange(Sender: TObject);
    procedure clrbtnClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure InfBtnClick(Sender: TObject);
    procedure InpEdKeyPress(Sender: TObject; var Key: char);
    procedure InpMem1Change(Sender: TObject);
    procedure InpMem2Change(Sender: TObject);
    procedure RecvTimerTimer(Sender: TObject);
    procedure ChangeDevCfg(Sender: TObject);
    procedure statbuttonClick(Sender: TObject);
    procedure statusLinesClick(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end; 

var
  MainForm: TMainForm;
  device:TBlockSerial;
  confdir: string;

implementation

uses Unit2;

{$R *.lfm}

{ TMainForm }

procedure TMainForm.FormCreate(Sender: TObject);
begin
  device := TBlockSerial.Create;
  {$IFDEF LINUX}
    device.LinuxLock := false; // Fehler beim debuggen, wird aber abgefangen (später auskommentieren?)
  {$ENDIF}
  confdir := GetAppConfigDir(False);
  if not DirectoryExists(confdir) then
  begin
    CreateDir(confdir);
    MessageDlg ('This is the first start.Create config directory "'+confdir+'"',
      mtInformation,[mbOk],0)
  end
  else
  if FileExists(confdir+'devEdit.items') then
     devEdit.Items.LoadFromFile(confdir+'devEdit.items');
end;

procedure TMainForm.clrbtnClick(Sender: TObject);
begin
  InpMem1.Clear;
  InpMem2.Clear;
end;

procedure TMainForm.cbcrChange(Sender: TObject);
begin

end;

procedure TMainForm.cbcrlfChange(Sender: TObject);
begin

end;

procedure TMainForm.FormDestroy(Sender: TObject);
begin
  FreeAndNil(device);
end;

procedure TMainForm.InfBtnClick(Sender: TObject);
begin
  InfoForm.ShowModal;
end;

procedure TMainForm.InpEdKeyPress(Sender: TObject; var Key: char);
var outstr: string;
begin
  if (Key = #13) and (device.InstanceActive) then
  begin
    if cbcr.checked then
      if cbcrlf.Checked then
        outstr := InpEd.Text+#13+#10
      else
        outstr := InpEd.Text+#13;
    device.SendString(outstr);
    if cbecho.Checked then
    begin
      InpMem1.Text := InpMem1.Text+InpEd.Text;
      InpMem2.Text := InpMem2.Text+StrToHex(InpEd.Text)+#13+#10;
    end;
  end;
end;

procedure TMainForm.InpMem1Change(Sender: TObject);
begin
  InpMem1.SelStart := Length(InpMem1.Lines.Text);
  if (cbaclr.Checked) and (InpMem1.Lines.Count > 19) then InpMem1.Lines.Delete(0);
end;

procedure TMainForm.InpMem2Change(Sender: TObject);
begin
  InpMem2.SelStart := Length(InpMem2.Lines.Text);
  if (cbaclr.Checked) and (InpMem2.Lines.Count > 19) then InpMem2.Lines.Delete(0);
end;

procedure TMainForm.RecvTimerTimer(Sender: TObject);
var
  c: char;
begin
  while device.WaitingDataEx > 0 do
  begin
    c := char(device.RecvByte(0));
    InpMem1.Lines.Text := InpMem1.Lines.Text + c;
    InpMem2.Lines.Text := InpMem2.Lines.Text+IntToHex(ord(c),2)+' ';
    if Length(InpMem2.Lines[InpMem2.Lines.Count-1]) > 47 then
      InpMem2.Text:=InpMem2.Text+#13+#10;
  end;

  if device.CTS then shCTS.Brush.Color:= clLime else shCTS.Brush.Color:= clBtnFace;
  if device.DSR then shDSR.Brush.Color:= clLime else shDSR.Brush.Color:= clBtnFace;
  if device.RING then shRI.Brush.Color:= clLime else shRI.Brush.Color:= clBtnFace;
  if device.Carrier then shCD.Brush.Color:= clLime else shCD.Brush.Color:= clBtnFace;
end;

procedure TMainForm.ChangeDevCfg(Sender: TObject);
var
  baud:integer;
  p: char;
  hardflow,softflow: boolean;
begin
  if device.InstanceActive then
  begin
    case cbParity.ItemIndex of
      0: p := 'N'; // none
      1: p := 'O'; // odd
      2: p := 'E'; // even
      3: p := 'M'; // mark
      4: p := 'S'; // space
    end;
    case cbHands.ItemIndex of
      0: hardflow := true;
      1: softflow := true;
      2: begin hardflow := true; softflow := true; end;
    end;
    baud := strtoint(cbBaud.Items[cbBaud.ItemIndex]);

    case cbStopb.ItemIndex of
      0: device.Config(baud,seDatab.Value,p,SB1,hardflow,softflow);
      1: device.Config(baud,seDatab.Value,p,SB1andHalf,hardflow,softflow);
      2: device.Config(baud,seDatab.Value,p,SB2,hardflow,softflow);
    end;

  end;
end;


procedure TMainForm.statbuttonClick(Sender: TObject);
var
  exists: boolean=false;
  i: integer;
begin
  if device.InstanceActive = false then
  begin
    device.Connect(devEdit.Text);
    if device.LastError <> 0 then
        MessageDlg ('connection error', 'Error: Device in use or not available !',
        mtError,[mbOk],0)
    else
    begin
      statbutton.Caption := 'Disconnect';
      devEdit.Enabled:=false;
      ChangeDevCfg(self);
      RecvTimer.Enabled := true;
      for i:=0 to devEdit.Items.Count-1 do
        if devEdit.Items[i]=devEdit.Caption then exists:=true;
      if not exists then
      begin
        devEdit.Items.Add(devEdit.Caption);
        devEdit.Items.SaveToFile(confdir+'devEdit.items');
      end;
    end;
  end
  else
  begin
    statbutton.Caption := 'Connect';
    devEdit.Enabled:=true;
    RecvTimer.Enabled:= false;
    device.CloseSocket;
    statuslinesClick(self);
  end;
end;

procedure TMainForm.statusLinesClick(Sender: TObject);
begin
  if device.InstanceActive then
  begin
    device.DTR:=dtrbtn.Down;
    device.RTS:=rtsbtn.Down;
  end
  else
  begin
    dtrbtn.Down:=false;
    rtsbtn.Down:=false;
  end;
end;

end.

